package com.socio.resources;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import org.apache.commons.codec.binary.Base64;

import com.google.appengine.repackaged.org.json.JSONObject;
import com.socio.behaviors.DAOBehavior;
import com.socio.behaviors.UserFacebookIDBehavior;
import com.socio.model.User;
import com.socio.utils.FieldAccessor.FieldAccessorField;

@Path("/oauth")
public class OAuthResource {
	
	private final String appSecret = "6f7052c7dde7ef72d1d0eec933cc7d10";
	
	/**
	 * Extracts parameters from a POST
	 * 
	 * @param parameterString POST params
	 * @return map of params and values
	 */
	private HashMap<String,String> getParamsMap(String parameterString) {
		HashMap<String,String> paramsMap = new HashMap<String,String>();
		String params[] = parameterString.split("&");
	    for (String param : params) {
	       String temp[] = param.split("=");
	       if(temp.length >= 2)
	    	   paramsMap.put(temp[0], temp[1]);
	    }
	    
	    return paramsMap;
	}
	
	@SuppressWarnings("unchecked")
	@Path("/deauthorize")
    @POST
    @Produces(MediaType.TEXT_PLAIN)
	public String handleDeauthorization(String signedRequestString) throws Exception {
		
		// preliminary checks before any real work gets done
		String signedRequest = getParamsMap(signedRequestString).get("signed_request");
		if(signedRequest == null)
			return "error";
		String[] sigJSON = signedRequest.split("\\.", 2);
		byte[] signature = new Base64(true).decode(sigJSON[0].getBytes());
		JSONObject jsonObject = new JSONObject(new String(new Base64(true).decode(sigJSON[1])));
		
		// check algorithm
		if(!jsonObject.getString("algorithm").equalsIgnoreCase("HMAC-SHA256"))
			return "error";
		
		// check signature
		Mac mac = Mac.getInstance("HmacSHA256");
		SecretKeySpec secret = new SecretKeySpec(appSecret.getBytes(),"HmacSHA256");
		mac.init(secret);
		byte[] expectedSignature = mac.doFinal(sigJSON[1].getBytes());
		if(!Arrays.equals(expectedSignature, signature))
			return "error";

		// setup behaviors
        DAOBehavior userFacebookIDDAO = new UserFacebookIDBehavior();
		
        // find user with facebook id
		String facebookID = jsonObject.getString("user_id");
		Object result = userFacebookIDDAO.read(facebookID, null);
		List<User> dbUsersWithFacebookID = (List<User>)result;
		
		// loop and reset all user facebookID's in cases where user uses Socio on 2 phones
		for(User dbUserWithFacebookID : dbUsersWithFacebookID) {
			if(dbUserWithFacebookID == null)
				continue;
			userFacebookIDDAO.update(facebookID, Arrays.asList(FieldAccessorField.UserFacebookID),
        		Arrays.asList((Object)""), null);
		}
        
        return "done";
	}
}
